home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / qix.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  6KB  |  232 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13.  
  14. unsigned char *qix_palettebank;
  15. unsigned char *qix_videoaddress;
  16.  
  17. /*#define DEBUG_LEDS*/
  18.  
  19. #ifdef DEBUG_LEDS
  20. #include <stdio.h>
  21. static FILE *led_log;
  22. #endif
  23.  
  24.  
  25. /***************************************************************************
  26.  
  27.   Convert the color PROMs into a more useable format.
  28.  
  29.   Qix doesn't have colors PROMs, it uses RAM. The meaning of the bits are
  30.   bit 7 -- Red
  31.         -- Red
  32.         -- Green
  33.         -- Green
  34.         -- Blue
  35.         -- Blue
  36.         -- Intensity
  37.   bit 0 -- Intensity
  38.  
  39. ***************************************************************************/
  40. static void update_pen (int pen, int val)
  41. {
  42.     /* this conversion table should be about right. It gives a reasonable */
  43.     /* gray scale in the test screen, and the red, green and blue squares */
  44.     /* in the same screen are barely visible, as the manual requires. */
  45.     static unsigned char table[16] =
  46.     {
  47.         0x00,    /* value = 0, intensity = 0 */
  48.         0x12,    /* value = 0, intensity = 1 */
  49.         0x24,    /* value = 0, intensity = 2 */
  50.         0x49,    /* value = 0, intensity = 3 */
  51.         0x12,    /* value = 1, intensity = 0 */
  52.         0x24,    /* value = 1, intensity = 1 */
  53.         0x49,    /* value = 1, intensity = 2 */
  54.         0x92,    /* value = 1, intensity = 3 */
  55.         0x5b,    /* value = 2, intensity = 0 */
  56.         0x6d,    /* value = 2, intensity = 1 */
  57.         0x92,    /* value = 2, intensity = 2 */
  58.         0xdb,    /* value = 2, intensity = 3 */
  59.         0x7f,    /* value = 3, intensity = 0 */
  60.         0x91,    /* value = 3, intensity = 1 */
  61.         0xb6,    /* value = 3, intensity = 2 */
  62.         0xff    /* value = 3, intensity = 3 */
  63.     };
  64.  
  65.     int bits,intensity,red,green,blue;
  66.  
  67.     intensity = (val >> 0) & 0x03;
  68.     bits = (val >> 6) & 0x03;
  69.     red = table[(bits << 2) | intensity];
  70.     bits = (val >> 4) & 0x03;
  71.     green = table[(bits << 2) | intensity];
  72.     bits = (val >> 2) & 0x03;
  73.     blue = table[(bits << 2) | intensity];
  74.  
  75.     palette_change_color(pen,red,green,blue);
  76. }
  77.  
  78.  
  79.  
  80. /***************************************************************************
  81.  
  82.   Start the video hardware emulation.
  83.  
  84. ***************************************************************************/
  85. int qix_vh_start(void)
  86. {
  87.     if ((videoram = malloc(256*256)) == 0)
  88.         return 1;
  89.  
  90. #ifdef DEBUG_LEDS
  91.     led_log = fopen ("led.log","w");
  92. #endif
  93.  
  94.     return 0;
  95. }
  96.  
  97.  
  98.  
  99. /***************************************************************************
  100.  
  101.   Stop the video hardware emulation.
  102.  
  103. ***************************************************************************/
  104. void qix_vh_stop(void)
  105. {
  106.     free (videoram);
  107.     videoram = 0;
  108.  
  109. #ifdef DEBUG_LEDS
  110.     if (led_log) fclose (led_log);
  111.     led_log = 0;
  112. #endif
  113. }
  114.  
  115.  
  116.  
  117. /* The screen is 256x256 with eight bit pixels (64K).  The screen is divided
  118. into two halves each half mapped by the video CPU at $0000-$7FFF.  The
  119. high order bit of the address latch at $9402 specifies which half of the
  120. screen is being accessed.
  121.  
  122. The address latch works as follows.  When the video CPU accesses $9400,
  123. the screen address is computed by using the values at $9402 (high byte)
  124. and $9403 (low byte) to get a value between $0000-$FFFF.  The value at
  125. that location is either returned or written. */
  126.  
  127. READ_HANDLER( qix_videoram_r )
  128. {
  129.     offset += (qix_videoaddress[0] & 0x80) * 0x100;
  130.     return videoram[offset];
  131. }
  132.  
  133. WRITE_HANDLER( qix_videoram_w )
  134. {
  135.     int x, y;
  136.  
  137.     offset += (qix_videoaddress[0] & 0x80) * 0x100;
  138.  
  139.     x = offset & 0xff;
  140.     y = offset >> 8;
  141.  
  142.     plot_pixel(Machine->scrbitmap, x, y, Machine->pens[data]);
  143.  
  144.     videoram[offset] = data;
  145. }
  146.  
  147.  
  148.  
  149. READ_HANDLER( qix_addresslatch_r )
  150. {
  151.     offset = qix_videoaddress[0] * 0x100 + qix_videoaddress[1];
  152.     return videoram[offset];
  153. }
  154.  
  155.  
  156.  
  157. WRITE_HANDLER( qix_addresslatch_w )
  158. {
  159.     int x, y;
  160.  
  161.     offset = qix_videoaddress[0] * 0x100 + qix_videoaddress[1];
  162.  
  163.     x = offset & 0xff;
  164.     y = offset >> 8;
  165.  
  166.     plot_pixel(Machine->scrbitmap, x, y, Machine->pens[data]);
  167.  
  168.     videoram[offset] = data;
  169. }
  170.  
  171.  
  172.  
  173. /* The color RAM works as follows.  The color RAM contains palette values for
  174. four pages (0-3).  When a write to $8800 on the video CPU occurs, the color
  175. RAM page is taken from the lowest 2 bits of the value.  This selects one of
  176. the color RAM pages as follows:
  177.  
  178.      colorRAMAddr = 0x9000 + ((data & 0x03) * 0x100);
  179.  
  180. Qix uses a palette of 64 colors (2 each RGB) and four intensities (RRGGBBII).
  181. */
  182. WRITE_HANDLER( qix_paletteram_w )
  183. {
  184.     paletteram[offset] = data;
  185.  
  186.     if ((*qix_palettebank & 0x03) == (offset / 256))
  187.         update_pen (offset % 256, data);
  188. }
  189.  
  190.  
  191.  
  192. WRITE_HANDLER( qix_palettebank_w )
  193. {
  194.     if ((*qix_palettebank & 0x03) != (data & 0x03))
  195.     {
  196.         unsigned char *pram = &paletteram[256 * (data & 0x03)];
  197.         int i;
  198.  
  199.         for (i = 0;i < 256;i++)
  200.             update_pen (i, *pram++);
  201.     }
  202.  
  203.     *qix_palettebank = data;
  204.  
  205. #ifdef DEBUG_LEDS
  206.     data = ~(data) & 0xfc;
  207.     if (led_log)
  208.     {
  209.         fprintf (led_log, "LEDS: %d %d %d %d %d %d\n", (data & 0x80)>>7, (data & 0x40)>>6,
  210.             (data & 0x20)>>5, (data & 0x10)>>4, (data & 0x08)>>3, (data & 0x04)>>2 );
  211.     }
  212. #endif
  213. }
  214.  
  215.  
  216. void qix_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  217. {
  218.     /* recalc the palette if necessary */
  219.     if (palette_recalc () || full_refresh)
  220.     {
  221.         int offs;
  222.  
  223.         for (offs = 0; offs < 256*256; offs++)
  224.         {
  225.             int x = offs & 0xff;
  226.             int y = offs >> 8;
  227.  
  228.             plot_pixel(bitmap, x, y, Machine->pens[videoram[offs]]);
  229.         }
  230.     }
  231. }
  232.